/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Busquedas;

import Estados.*;
import Juegos.*;
import java.util.ArrayList;

/**
 *
 * @author Alvaro
 */
public class ProfundidadLimitada extends Busqueda{

    ArrayList<Estado> expandidos;
    ArrayList<ProfLimEstado> pilaAbiertos;
    int maxProfundidad;


    public ProfundidadLimitada(Estado ini,Juego juego,int p){
        super(ini,juego);
        this.expandidos=new ArrayList<Estado>();
        this.pilaAbiertos=new ArrayList<ProfLimEstado>();
        ProfLimEstado e=new ProfLimEstado(ini);
        this.pilaAbiertos.add(e);
        this.maxProfundidad=p;
    }

    public void resetExpandidos(){
        this.expandidos.clear();
    }

    public void resetAbiertos(){
        this.pilaAbiertos.clear();
        ProfLimEstado ple=new ProfLimEstado(this.inicial);
        this.pilaAbiertos.add(ple);
    }


    public ArrayList<Estado> resolver(){
        boolean solucion = false;
        while (!solucion && this.pilaAbiertos.size()!=0){
            int profundidad=this.pilaAbiertos.get(0).getProfundidad();
            Estado e=this.pilaAbiertos.remove(0).getEstado();
            if(juego.esFinal(e)){
                solucionar(e);
                solucion=true;
            }else if(this.maxProfundidad>profundidad){
                    generaHijos(e,profundidad);
            }
        }
        return this.solucion;
    }

    private void generaHijos(Estado e,int p){
        this.expandidos.add(e);
        int ops=this.juego.getNumOperadores();
        for(int i=0;i<ops;i++){
            Estado nuevo=this.juego.operar(i,e);
            if( nuevo!=null && !estaExpandido(nuevo) && !juego.esPeligro(nuevo)){
                ProfLimEstado pfe = new ProfLimEstado(nuevo, p + 1);
                this.pilaAbiertos.add(0, pfe);
            }
        }
    }

    private boolean estaExpandido(Estado e){
        for(int i=0;i<this.expandidos.size();i++){
            if(e.Iguales(e, this.expandidos.get(i)))
                return true;
        }
        return false;
    }
    public void setMaxProfundidad(int m){
        this.maxProfundidad=m;
    }

    public int getMaxProfundidad(){
        return this.maxProfundidad;
    }

}
